// Copyright Epic Games, Inc. All Rights Reserved.

#pragma once

#include "GameFramework/Actor.h"

#include "LyraWeaponSpawner.generated.h"

// 定义API宏
#define UE_API LYRAGAME_API

namespace EEndPlayReason { enum Type : int; }

class APawn;
class UCapsuleComponent;
class ULyraInventoryItemDefinition;
class ULyraWeaponPickupDefinition;
class UObject;
class UPrimitiveComponent;
class UStaticMeshComponent;
struct FFrame;
struct FGameplayTag;
struct FHitResult;

/**
 * 武器生成器Actor，用于在关卡中生成可拾取的武器
 */
UCLASS(MinimalAPI, Blueprintable,BlueprintType)
class ALyraWeaponSpawner : public AActor
{
	GENERATED_BODY()
	
public:	
	// 设置此Actor的属性的默认值
	UE_API ALyraWeaponSpawner();

protected:
	// 游戏开始或生成时调用
	UE_API virtual void BeginPlay() override;
	// 游戏结束时调用
	UE_API virtual void EndPlay(const EEndPlayReason::Type EndPlayReason) override;

public:	
	// 每帧调用
	UE_API virtual void Tick(float DeltaTime) override;

	// 构建时调用
	UE_API void OnConstruction(const FTransform& Transform) override;

protected:
	// 用于配置武器生成器的数据资产
	UPROPERTY(EditInstanceOnly, BlueprintReadOnly, Category = "Lyra|WeaponPickup")
	TObjectPtr<ULyraWeaponPickupDefinition> WeaponDefinition;

	// 武器是否可用（已复制，使用OnRep函数）
	UPROPERTY(EditDefaultsOnly, BlueprintReadWrite, ReplicatedUsing = OnRep_WeaponAvailability, Category = "Lyra|WeaponPickup")
	bool bIsWeaponAvailable;

	// 武器拾取和武器生成之间的时间（秒）
	UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Lyra|WeaponPickup")
	float CoolDownTime;

	// 武器变为可用后检查Pawn站在生成器上的延迟。用于给bIsWeaponAvailable的OnRep时间触发和播放特效。
	UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Lyra|WeaponPickup")
	float CheckExistingOverlapDelay;

	// 用于驱动武器重生时间指示器0-1
	UPROPERTY(BlueprintReadOnly, Transient, Category = "Lyra|WeaponPickup")
	float CoolDownPercentage;

public:
	// 碰撞体积组件
	UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Lyra|WeaponPickup")
	TObjectPtr<UCapsuleComponent> CollisionVolume;

	// 底座网格组件
	UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Lyra|WeaponPickup")
	TObjectPtr<UStaticMeshComponent> PadMesh;

	// 武器网格组件
	UPROPERTY(BlueprintReadOnly, Category = "Lyra|WeaponPickup")
	TObjectPtr<UStaticMeshComponent> WeaponMesh;

	// 武器网格旋转速度
	UPROPERTY(EditDefaultsOnly, BlueprintReadWrite, Category = "Lyra|WeaponPickup")
	float WeaponMeshRotationSpeed;

	// 冷却计时器句柄
	FTimerHandle CoolDownTimerHandle;

	// 检查重叠延迟计时器句柄
	FTimerHandle CheckOverlapsDelayTimerHandle;

	/**
	 * 重叠开始事件处理函数。
	 * @param OverlappedComponent 重叠的组件
	 * @param OtherActor 其他Actor
	 * @param OtherComp 其他组件
	 * @param OtherBodyIndex 其他身体索引
	 * @param bFromSweep 是否来自扫描
	 * @param SweepHitResult 扫描命中结果
	 */
	UFUNCTION()
	UE_API void OnOverlapBegin(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepHitResult);

	// 武器生成时检查站在垫子上的Pawn。
	UE_API void CheckForExistingOverlaps();

	/**
	 * 尝试拾取武器（蓝图原生事件）。
	 * @param Pawn 尝试拾取的Pawn
	 */
	UFUNCTION(BlueprintNativeEvent)
	UE_API void AttemptPickUpWeapon(APawn* Pawn);

	/**
	 * 给予武器（蓝图可实现事件）。
	 * @param WeaponItemClass 武器物品类
	 * @param ReceivingPawn 接收的Pawn
	 * @return 返回是否成功给予武器
	 */
	UFUNCTION(BlueprintImplementableEvent, Category = "Lyra|WeaponPickup")
	UE_API bool GiveWeapon(TSubclassOf<ULyraInventoryItemDefinition> WeaponItemClass, APawn* ReceivingPawn);

	// 开始冷却
	UE_API void StartCoolDown();

	/**
	 * 重置冷却（蓝图可调用）。
	 */
	UFUNCTION(BlueprintCallable, Category = "Lyra|WeaponPickup")
	UE_API void ResetCoolDown();

	/**
	 * 冷却计时器完成回调。
	 */
	UFUNCTION()
	UE_API void OnCoolDownTimerComplete();

	// 设置武器拾取可见性
	UE_API void SetWeaponPickupVisibility(bool bShouldBeVisible);

	/**
	 * 播放拾取特效（蓝图原生事件）。
	 */
	UFUNCTION(BlueprintNativeEvent, Category = "Lyra|WeaponPickup")
	UE_API void PlayPickupEffects();

	/**
	 * 播放重生特效（蓝图原生事件）。
	 */
	UFUNCTION(BlueprintNativeEvent, Category = "Lyra|WeaponPickup")
	UE_API void PlayRespawnEffects();

	/**
	 * 武器可用性复制通知函数。
	 */
	UFUNCTION()
	UE_API void OnRep_WeaponAvailability();

	/** 在物品定义类型中搜索匹配的统计信息并返回值，如果未找到则返回0 */
	UFUNCTION(BlueprintCallable, BlueprintPure, Category = "Lyra|WeaponPickup")
	static UE_API int32 GetDefaultStatFromItemDef(const TSubclassOf<ULyraInventoryItemDefinition> WeaponItemClass, FGameplayTag StatTag);
};

// 取消定义API宏
#undef UE_API